package cn.ilikes.tools.nosql.jpa.persistences.contexts.operations;

import cn.ilikes.tools.nosql.jpa.clients.Client;
import cn.ilikes.tools.nosql.jpa.clients.JPASQLClientsException;
import cn.ilikes.tools.nosql.jpa.graphs.Node;
import cn.ilikes.tools.nosql.jpa.graphs.NodeLifeCycle;
import cn.ilikes.tools.nosql.jpa.graphs.NodeLifeCycle.LifeCycle;
import cn.ilikes.tools.nosql.jpa.metadatas.EntityMetaData;
import cn.ilikes.tools.nosql.jpa.persistences.contexts.AbstractContext;
import cn.ilikes.tools.nosql.jpa.persistences.contexts.Operation;
import cn.ilikes.tools.nosql.jpa.persistences.contexts.OperationRunTimeException;

public class FindOperation extends ContextOperation implements Operation<Node> {

	private Class<?> entityClass;

	private Object key;

	public FindOperation(AbstractContext context, Class<?> entityClass, Object key) {
		super(OperationType.find, context);
		this.entityClass = entityClass;
		this.key = key;

	}

	@Override
	public Node exec() {
		AbstractContext abstractContext = getContext();
		Client client = abstractContext.getClient();
		try {
			AbstractContext context = getContext();
			EntityMetaData entityMetaData = context.getPersistenUnitEnv().getMetaDataManagerFactory().selectIEntityMetaData(entityClass);
			Node node = context.getCache(key, entityMetaData);
			if (node != Node.NULL_NODE && node.getNodeLifeCycle().getLifeCycle().equals(NodeLifeCycle.LifeCycle.managed))
				return node;
			node = client.findById(entityMetaData, key);
			if (node == null)
				return Node.NULL_NODE;
			Node.switchNodeLifeCycle(node, LifeCycle.managed);
			abstractContext.putCache(key, node);
			return node;
		} catch (JPASQLClientsException e) {
			throw new OperationRunTimeException(e);
		}

	}

	@Override
	public boolean rollback() {
	
		return true;
	}

}
